package com.adopapa.ethexplorer.contoller;

import java.net.URI;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.exception.ExceptionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.web.reactive.function.server.ServerResponse;

import com.adopapa.ethexplorer.conf.AppContextUtil;
import com.adopapa.ethexplorer.domain.UserInfo;
import com.adopapa.ethexplorer.domain.UserInfo.UserType;
import com.adopapa.ethexplorer.service.RedisService;
import com.adopapa.ethexplorer.service.UserInfoService;
import com.adopapa.ethexplorer.utils.Tools;

import reactor.core.publisher.Mono;

public abstract class BaseController {

	protected Logger logger = LoggerFactory.getLogger(getClass());

	protected Map<String, Object> ok(String message, Object result) {
		Map<String, Object> response = new LinkedHashMap<String, Object>();
		response.put("code", "01");
		response.put("message", message);
		response.put("result", result);
		return response;

	}

	protected Map<String, Object> ko(String message) {
		Map<String, Object> response = new LinkedHashMap<String, Object>();
		response.put("code", "01");
		response.put("message", message);
		return response;
	}

	protected Map<String, Object> ok() {
		Map<String, Object> response = new LinkedHashMap<String, Object>();
		response.put("code", "01");
		response.put("message", "请求成功！");
		return response;
	}

	protected Map<String, Object> ok(Object result) {
		Map<String, Object> response = new LinkedHashMap<String, Object>();
		response.put("code", "01");
		response.put("message", "请求成功！");
		response.put("result", result);
		return response;

	}

	protected Map<String, Object> other(String message) {
		Map<String, Object> response = new LinkedHashMap<String, Object>();
		response.put("code", "04");
		response.put("message", message);
		return response;
	}

	protected Map<String, Object> other(String message, Object result) {
		Map<String, Object> response = new LinkedHashMap<String, Object>();
		response.put("code", "04");
		response.put("message", message);
		response.put("result", result);
		return response;

	}

	protected Map<String, Object> error(Exception e) {
		logger.error(ExceptionUtils.getStackTrace(e));
		Map<String, Object> response = new LinkedHashMap<String, Object>();
		response.put("code", "00");
		response.put("message", e.getMessage() == null ? "请求失败,请确认权限！" : e.getMessage());
		return response;
	}

	protected Map<String, String> getUserInfoCached(String authorization) {
		RedisService redisService = //
				AppContextUtil.getAppContext().getBean(RedisService.class);

		Map<String, String> userInfo = redisService.getUserInfo(authorization);

		return userInfo;
	}

	protected UserInfo getUserInfo(String authorization) {
		Map<String, String> userInfoCached = getUserInfoCached(authorization);
		if (Tools.empty(userInfoCached)) {
			throw new RuntimeException("会话失效请重新登陆");
		}
		UserInfoService userInfoService = AppContextUtil.getAppContext().getBean(UserInfoService.class);
		UserInfo userInfo = userInfoService.getUserInfoById(userInfoCached.get("userId"));
		if (Tools.empty(userInfo)) {
			throw new RuntimeException("会话失效请重新登陆");
		}

		return userInfo;
	}
	

	protected void checkAdmin(String authorization) {
		Map<String, String> userInfo = getUserInfoCached(authorization);
		if (Tools.empty(userInfo)) {
			throw new RuntimeException("No Permissions!");
		}
		String userType = userInfo.get("userType");

		if (UserType.OPERATOR.name().equalsIgnoreCase(userType)) {
			throw new RuntimeException("No Permissions!");
		}

	}

	protected Mono<ServerResponse> redirect(String targetUrl) {

		return ServerResponse.temporaryRedirect(URI.create(targetUrl)).build();
	}

	// -Djava.net.preferIPv4Stack=true
	protected String getRemoteIp(ServerHttpRequest request) {
		return request.getRemoteAddress().getAddress().getHostAddress();

	}

	@SuppressWarnings("unchecked")
	protected static <T> T getMapValue(Map<String, Object> paramMap, String key, Class<T> klazz) {
		// FIXME
		if (paramMap == null || paramMap.isEmpty()) {
			return null;
		}
		if (klazz == String.class) {
			return (T) paramMap.get(key);
		}
		if (klazz == Integer.class || klazz == int.class) {
			return (T) (Integer) Integer.parseInt(String.valueOf(paramMap.get(key)));
//			return (T) (Integer) paramMap.get(key);
		}
		if (klazz == Double.class || klazz == double.class) {
			return (T) (Double) Double.parseDouble(String.valueOf(paramMap.get(key)));
//			return (T) (Double) paramMap.get(key);
		}
		if (klazz == Boolean.class || klazz == boolean.class) {
			return (T) (Boolean) Boolean.valueOf(String.valueOf(paramMap.get(key)));
//			return (T) (Boolean) paramMap.get(key);
		}
//		if (klazz == Date.class) {
//			return (T) Tools.getLongDate(String.valueOf(paramMap.get(key)));
//		}
		if (klazz == List.class) {
			return (T) paramMap.get(key);
		}
		return (T) paramMap.get(key);
	}

}
